"use strict";
import lscache from "lscache";
import hash from "object-hash";
import $ from "jquery";
import _ from "lodash";

import { assert } from "../common/assert.js";
import { ajaxCall, APIDOMAIN, getToken } from "../common/apihelper.js";
import { UserActions } from "../action/useraction.js";


var API_CACHETIME = 5;

var StoreMixin = {
    _pack: function(key, api_data){
        var data = lscache.get(this.cacheKey);
        if(data == null){
            data = {};
        }
        var cacheData = data[key];

        // if(key != null){
        //     if(JSON.stringify(cacheData) == JSON.stringify(api_data)){
        //         // 数据没有变化
        //         return;
        //     }
        // }

        data[key] = api_data;
        lscache.set(this.cacheKey, data, 999999);
        data.params = this.params;

        // bind state
        var state = lscache.get(this.cacheKey + '-state');
        data.state = state;

        // bind status
        var status = _.get(this, 'status', {});
        data.status = status;
        return data;
    },
    pack: function(key, api_data){
        var data = this._pack(key, api_data);
        // 保存一个永久备份的数据，用于 getInitlize 在长时间等待之后的首次获取
        // lscache.set(this.cacheKey+'-forever', data, 999999);
        this.trigger(data);
    },
    fetch: function(key, api_name, params){
        // 先尝试从缓存获取
        console.log(api_name);
        var cacheKey = api_name + hash.MD5(params);

        var api_data = null;

        var ds_data_updated = lscache.get('ds_data_updated' + cacheKey);

        api_data = lscache.get(cacheKey);

        var markDone = function(key){
            this.status[key] = 'FETCH-DONE';
        }.bind(this)

        if(api_data != null){
            markDone(key);
            this.pack(key, api_data);
            if (ds_data_updated) {
                return;
            }
        }

        var callback = function(response){
            var api_data = response;
            lscache.set(cacheKey, api_data, 999999); //永久存储
            lscache.set('ds_data_updated'+cacheKey, true, API_CACHETIME);

            markDone(key);
            this.pack(key, api_data);
        }.bind(this);

        ajaxCall('/v1/exchange/data/query/' + api_name, params, callback);
        //this.fakeData(key, api_name, params);
    },
    onFetchData: function(params){
        var apis = $.extend(true, {}, this.apis);
        // 更新参数
        _(params).forOwn(function(val, key){
            if(val == null){
                return
            }
            if(key == 'apiCollections'){
                // 其它API组
                for(var i=0; i<val.length; i++){
                    var apiGroupName = 'apis_' + val[i]; 
                    var otherApis = this[apiGroupName];
                    assert(otherApis != null);
                    // 添加到 apis
                    _(otherApis).forOwn(function(val, key){
                        apis[key] = val;
                    }).value();
                } 
            }
            else{
                this.params[key] = val;
            }
        }.bind(this)).value();

        // 请求数据之前标记正要更新的数据
        if(this.status == null){
            this.status = {};
        }
        _(apis).forOwn(function(val, key){
            this.status[key] = 'FETCHING';
        }.bind(this)).value();
        this.pack();

        // 请求数据
        _(apis).forOwn(function(val, key){
            // 准备参数
            var params = {};
            _(val.params).forOwn(function (name) {
                // 处理参数冲突, api_indicator + '_' + paraname
                var specName = key + '_' + name;
                if (_.has(this.params, specName)) {
                    params[name] = this.params[specName];
                }
                else {
                    params[name] = this.params[name];
                }
            }.bind(this)).value()

            var api_name = key;
            if (_.has(val, 'name') == true) {
                api_name = val.name;
            }

            // 请求数据
            this.fetch(key, api_name, params);
        }.bind(this)).value()
    },
    onSaveState: function(params){
        var key = this.cacheKey + '-state';
        var data = lscache.get(key);
        if(!data){
            data = {}
        }
        _(params).forOwn(function(val, key){
            data[key] = val;
        }.bind(this)).value();
        lscache.set(key, data, 60 * 24 * 30);
        console.log('save state:', params)
    },
    getInitialState: function(){
        var data = this._pack();

        // 防止长时间不操作之后，cache过期，界面全部置空的情况
        // if(data == null){
        //     data = lscache.get(this.cacheKey+'-forever')
        // }

        return data;
    }
};


var getTradingDays = function(day, callback){
    var key = 'tradingdays-' + day.getFullYear();
    var data = lscache.get(key);
    if(data == null){
        var url = APIDOMAIN + "/v1/exchange/data/query/ds_trade_days";
        var params = {
            params:{year: day.getFullYear()}
        };
        //params['sign'] = 'H12B.904GD01.142N2E0I8B7DB0921416364.7652405G5D5.15ENB61AFEDI4ECJ0F6.005I22BA89296AB5709B9840F7886166049A01E9B929555790EE6E29C7F2';    
        params['sign'] = getToken();
        params = JSON.stringify(params);
        params = {_json: params, _method: 'GET', };    
        $.ajax({
            url:url,
            data:params,
            dataType:'jsonp',
            type: 'POST',
            // jsonp: "cb",
            beforeSend: function(xhr, settings) { xhr.setRequestHeader('contentType','application/json; charset=utf-8'); },
            error: function(XMLHttpRequest, textStatus, errorThrown){
                // 错误处理
                
            },
            success: function(response){
                if (response.err == 0) {
                    var data = response.data;
                    data = data.map(function(item){
                        return item.vdate;
                    })
                    lscache.set(key, data, 60*24);
                    if(callback != null){
                        data = data.sort()
                        data = data.map(function(val){return new Date(val)})
                        callback(data);
                    }
                } else if(response.err == 4015){
                    // token 过期或无效, 重新登录
                    console.log('token 过期');
                    UserActions.logout();
                }
                else{
                    // 错误处理, 开启
                    console.warn("Api call fail:", url, response.Msg);
                }         
            } 
        })
    }
    else{
        if(callback != null){
            data = data.sort()
            data = data.map(function(val){return new Date(val)})
            callback(data);
        }
    }
} 

var getLastTradingDay = function(day, callback){
    // callback 接收参数 lastTradingDay, lastTradingDayIndex, allTradingDays
    var myCallback = function(data){
        data.reverse();
        for(var i=0; i<data.length; i++){
            var d = data[i];
            if(d < day){
                callback(d, i, data)
                break
            }
        }
        if (Date.parse(data[data.length - 1]) >= Date.parse(day)) {
            var date = new Date(day.getFullYear() - 1, 11, 31, 12);
            getTradingDays(date, myCallback);
        }
    }
    getTradingDays(day, myCallback);
}

export { StoreMixin, getTradingDays, getLastTradingDay };